package com.ae.putingotdown.util;

import com.ae.putingotdown.Config;
import com.ae.putingotdown.block.PlacedIngot;
import com.ae.putingotdown.block.Register;
import com.ae.putingotdown.block.TilePlacedItem;
import com.ae.putingotdown.cap.SingleItemStackHandler;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;

import javax.annotation.Nonnull;

public class PutItemAction {
    public static void put(World world, BlockPos pos, Direction face, ItemStack stack, Direction playerDirection, boolean cycled) {
        TileEntity tileEntity = world.getBlockEntity(pos);

        //所在位置方块实体不是TilePlacedIngot。
        if (!(tileEntity instanceof TilePlacedItem)) {
            //点击位置为上表面，生成锭方块
            if (face == Direction.UP) {
                if (cycled) {
                    putItemDown(world, pos, stack, playerDirection);
                } else {
                    putItemDown(world, pos.above(), stack, playerDirection);
                }
            }
            return;
        }

        SingleItemStackHandler handler = ((TilePlacedItem) tileEntity).handler;

        //持有的物品与已存储的物品不符，结束。
        if (!handler.isItemValid(stack)) {
            return;
        }

        int spare = handler.getMaxCount() - handler.getStackInSlot().getCount();

        //如果剩余空间不足以放入一个锭则向上一格进行放置尝试。
        if (spare < 1) {
            put(world, pos.above(), Direction.UP, stack, playerDirection, true);
            return;
        }

        //锭放入方块中。
        putItemIn(stack, (TilePlacedItem) tileEntity);
    }

    /**
     * @param world 事件发生的世界
     * @param pos   事件发生的坐标
     * @param stack 触发事件发生的物品
     *              生成物品对应的方块，该方法不检测 World, BlockPos, Stack 是否真实有效。
     */
    private static void putItemDown(@Nonnull World world, @Nonnull BlockPos pos, @Nonnull ItemStack stack, Direction direction) {
        //如未给其设置颜色，以普通物品方式放置，否则以锭方块放置
        int color = Config.test(stack);

        if (color == -1 && !Config.CAN_ALL_PUT.get()) {
            return;
        }

        //不可放置则跳过
        if (!world.getBlockState(pos).is(Blocks.AIR)) {
            return;
        }

        ItemStack stack1 = stack.copy();
        stack1.setCount(1);
        stack.shrink(1);
        BlockState state = Register.PLACED_INGOT.get().defaultBlockState();
        state = state.setValue(PlacedIngot.DIRECTION, direction);
        world.setBlock(pos, color == -1 ? state : state.setValue(PlacedIngot.INGOT, true), 1);
        TilePlacedItem tile = (TilePlacedItem) world.getBlockEntity(pos);

        if (tile != null) {
            tile.handler.setStack(stack1);
            tile.setColor(color);
            world.sendBlockUpdated(tile.getBlockPos(), tile.getBlockState(), tile.getBlockState(), 1);
        }
    }

    private static void putItemIn(@Nonnull ItemStack stack, @Nonnull TilePlacedItem tile) {
        ItemStack stack1 = new ItemStack(stack.getItem(), 1);

        if (tile.handler.insertItem(stack1, false).isEmpty()) {
            stack.shrink(1);
        }
    }
}
